package dynomicTable

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"project-info/src/handle/response"
	"project-info/src/lib"
	"project-info/src/model"
	"gorm.io/gorm"
)

// SaveTableConfigRequest 保存表格配置请求结构
type SaveTableConfigRequest struct {
	Name           string            `json:"name"`
	Description    string            `json:"description"`
	DataPermission bool              `json:"dataPermission"`
	Fields         []model.FormField `json:"fields"`      // 可以是字符串或数组
	TableFields    []model.FormField `json:"tableFields"` // 可以是字符串或数组
}

// SaveTableConfig 保存表格配置
func SaveTableConfig(c *lib.GinContext) error {
	var req SaveTableConfigRequest
	if err := c.Bind(&req); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	// 转换为TableConfig模型
	var config model.TableConfig
	config.Name = req.Name
	config.Description = req.Description
	config.DataPermission = req.DataPermission
	config.Fields = model.FormFields(req.Fields)
	config.TableFields = model.FormFields(req.TableFields)

	// 验证配置名称
	if config.Name == "" {
		return response.JsonFail(c, "配置名称不能为空")
	}

	// 检查配置名称是否已存在
	var existingConfig model.TableConfig
	result := model.DB().Where("name = ?", config.Name).First(&existingConfig)
	if result.Error == nil {
		return response.JsonFail(c, "配置名称已存在")
	}

	if err := model.DB().Transaction(func(tx *gorm.DB) error {
		// 创建配置
		if err := tx.Create(&config).Error; err != nil {
			c.Logger().Error(err.Error())
			return err
		}

		// 根据配置创建对应的动态表
		if err := createDynamicTable(tx, config.Name, config.Fields); err != nil {
			c.Logger().Error(err.Error())
			return err
		}

		return nil
	}); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "保存配置失败")
	}
	return response.JsonOk(c, config, "保存成功")
}

// GetTableConfig 获取表格配置
func GetTableConfig(c *lib.GinContext) error {
	name := c.QueryParam("name")
	if name == "" {
		return response.JsonFail(c, "配置名称不能为空")
	}

	var config model.TableConfig
	if err := model.DB().Where("name = ?", name).First(&config).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	return response.JsonOk(c, config, "获取成功")
}

// ListTableConfig 获取配置列表
func ListTableConfig(c *lib.GinContext) error {
	type ListRequest struct {
		Page    int    `d:"1" json:"page"`
		Size    int    `d:"10" json:"size"`
		Keyword string `d:"" json:"keyword"`
	}

	var req ListRequest
	if err := c.Bind(&req); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	if req.Page <= 0 {
		req.Page = 1
	}
	if req.Size <= 0 {
		req.Size = 10
	}

	db := model.DB().Model(&model.TableConfig{})

	// 关键词搜索
	if req.Keyword != "" {
		db = db.Where("name LIKE ? OR description LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	// 获取总数
	var total int64
	db.Count(&total)

	// 分页查询
	var configs []model.TableConfig
	offset := (req.Page - 1) * req.Size
	if err := db.Offset(offset).Limit(req.Size).Order("update_time DESC").Find(&configs).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "查询失败")
	}

	result := map[string]interface{}{
		"records": configs,
		"total":   total,
		"page":    req.Page,
		"size":    req.Size,
	}

	return response.JsonOk(c, result, "获取成功")
}

// UpdateTableConfigRequest 更新表格配置请求结构
type UpdateTableConfigRequest struct {
	Id             uint64            `json:"id"`
	Name           string            `json:"name"`
	Description    string            `json:"description"`
	DataPermission bool              `json:"dataPermission"`
	Fields         []model.FormField `json:"fields"`      // 可以是字符串或数组
	TableFields    []model.FormField `json:"tableFields"` // 可以是字符串或数组
}

// UpdateTableConfig 更新表格配置
func UpdateTableConfig(c *lib.GinContext) error {
	var req UpdateTableConfigRequest
	if err := c.Bind(&req); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	if req.Id == 0 {
		return response.JsonFail(c, "配置ID不能为空")
	}

	// 转换为TableConfig模型
	var config model.TableConfig
	config.Id = uint64(req.Id)
	config.Name = req.Name
	config.Description = req.Description
	config.DataPermission = req.DataPermission
	config.Fields = model.FormFields(req.Fields)
	config.TableFields = model.FormFields(req.TableFields)

	// 检查配置是否存在
	var existingConfig model.TableConfig
	if err := model.DB().First(&existingConfig, uint64(req.Id)).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	// 如果名称发生变化，检查新名称是否已存在
	if req.Name != existingConfig.Name {
		var nameCheck model.TableConfig
		result := model.DB().Where("name = ? AND id != ?", req.Name, uint64(req.Id)).First(&nameCheck)
		if result.Error == nil {
			return fmt.Errorf("配置名称已存在")
		}
	}

	if err := model.DB().Transaction(func(tx *gorm.DB) error {
		// 如果名称发生变化，需要重命名动态表
		if req.Name != existingConfig.Name {
			if err := renameDynamicTable(tx, existingConfig.Name, req.Name); err != nil {
				c.Logger().Error(err.Error())
				return err
			}
		}

		// 检查字段是否发生变化，如果有变化则更新表结构
		if fieldsChanged(existingConfig.Fields, config.Fields) {
			if err := updateDynamicTableStructure(tx, config.Name, config.Fields); err != nil {
				c.Logger().Error(err.Error())
				return err
			}
		}

		// 更新配置
		if err := tx.Save(&config).Error; err != nil {
			c.Logger().Error(err.Error())
			return err
		}
		return nil
	}); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "更新失败")
	}
	return response.JsonOk(c, config, "更新成功")
}

// DeleteTableConfig 删除表格配置
func DeleteTableConfig(c *lib.GinContext) error {
	idStr := c.QueryParam("id")
	if idStr == "" {
		return response.JsonFail(c, "配置ID不能为空")
	}

	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return response.JsonFail(c, "配置ID格式错误")
	}

	// 获取配置信息
	var config model.TableConfig
	if err := model.DB().First(&config, uint(id)).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	// 删除配置
	if err := model.DB().Transaction(func(tx *gorm.DB) error {
		if err := tx.Delete(&config).Error; err != nil {
			c.Logger().Error(err.Error())
			return err
		}
		// 删除对应的动态表
		if err := dropDynamicTable(tx, config.Name); err != nil {
			c.Logger().Error(err.Error())
			return err
		}
		return nil
	}); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "删除失败")
	}

	return response.JsonOk(c, nil, "删除成功")
}

// createDynamicTable 根据配置创建动态表
func createDynamicTable(tx *gorm.DB, configName string, fields []model.FormField) error {
	tableName := "dynamic_table_" + configName

	// 构建创建表的SQL
	sql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS `%s` (", tableName)
	sql += "`id` BIGINT PRIMARY KEY AUTO_INCREMENT,"

	for _, field := range fields {
		columnType := getColumnType(field.Type)
		sql += fmt.Sprintf("`%s` %s,", field.Name, columnType)
	}

	sql += "`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,"
	sql += "`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
	sql += ")"

	return tx.Exec(sql).Error
}

// dropDynamicTable 删除动态表
func dropDynamicTable(tx *gorm.DB, configName string) error {
	tableName := "dynamic_table_" + configName
	sql := fmt.Sprintf("DROP TABLE IF EXISTS `%s`", tableName)
	return tx.Exec(sql).Error
}

// renameDynamicTable 重命名动态表
func renameDynamicTable(tx *gorm.DB, oldName, newName string) error {
	oldTableName := "dynamic_table_" + oldName
	newTableName := "dynamic_table_" + newName
	sql := fmt.Sprintf("RENAME TABLE `%s` TO `%s`", oldTableName, newTableName)
	return tx.Exec(sql).Error
}

// getColumnType 根据字段类型返回MySQL列类型
func getColumnType(fieldType string) string {
	switch strings.ToLower(fieldType) {
	case "text":
		return "VARCHAR(255)"
	case "textarea":
		return "TEXT"
	case "number":
		return "DECIMAL(10,2)"
	case "date":
		return "DATE"
	case "datetime":
		return "DATETIME"
	case "select", "radio", "checkbox":
		return "VARCHAR(500)" // 支持多选值
	case "file":
		return "VARCHAR(1000)" // 文件路径
	default:
		return "VARCHAR(255)"
	}
}

// fieldsChanged 检查字段配置是否发生变化
func fieldsChanged(oldFields, newFields model.FormFields) bool {
	oldJSON, _ := json.Marshal(oldFields)
	newJSON, _ := json.Marshal(newFields)
	return string(oldJSON) != string(newJSON)
}

// updateDynamicTableStructure 更新动态表结构
func updateDynamicTableStructure(tx *gorm.DB, configName string, newFields model.FormFields) error {
	tableName := "dynamic_table_" + configName

	// 获取当前表结构
	rows, err := tx.Raw("SHOW COLUMNS FROM `" + tableName + "`").Rows()
	if err != nil {
		return err
	}
	defer rows.Close()

	// 解析当前表的列信息
	existingColumns := make(map[string]bool)
	for rows.Next() {
		var field, fieldType, null, key, extra string
		var defaultValue sql.NullString
		if err := rows.Scan(&field, &fieldType, &null, &key, &defaultValue, &extra); err != nil {
			continue
		}
		// 跳过系统字段
		if field != "id" && field != "create_time" && field != "update_time" {
			existingColumns[field] = true
		}
	}

	// 添加新字段
	for _, field := range newFields {
		if !existingColumns[field.Name] {
			columnType := getColumnType(field.Type)
			addColumnSQL := fmt.Sprintf("ALTER TABLE `%s` ADD COLUMN `%s` %s", tableName, field.Name, columnType)
			if err := tx.Exec(addColumnSQL).Error; err != nil {
				return fmt.Errorf("添加字段 %s 失败: %v", field.Name, err)
			}
		}
	}

	// 检查需要删除的字段（存在于数据库但不在新配置中）
	newFieldsMap := make(map[string]bool)
	for _, field := range newFields {
		newFieldsMap[field.Name] = true
	}

	for columnName := range existingColumns {
		if !newFieldsMap[columnName] {
			// 删除不再需要的字段
			dropColumnSQL := fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN `%s`", tableName, columnName)
			if err := tx.Exec(dropColumnSQL).Error; err != nil {
				return fmt.Errorf("删除字段 %s 失败: %v", columnName, err)
			}
		}
	}

	return nil
}
